package com.example.controller;

import com.example.common.Result;
import com.example.entity.Document;
import com.example.service.DocumentService;
import com.example.service.KnowledgeSpaceService;
import com.example.service.MarkdownService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * 文件上传控制器
 */
@RestController
@RequestMapping("/api/upload")
public class FileUploadController {

    @Autowired
    private DocumentService documentService;

    @Autowired
    private KnowledgeSpaceService knowledgeSpaceService;

    @Value("${file.upload.path:uploads/documents}")
    private String uploadPath;

    /**
     * 上传文档文件
     */
    @PostMapping("/document")
    public Result uploadDocument(
            @RequestParam("file") MultipartFile file,
            @RequestParam("spaceId") Integer spaceId,
            @RequestParam("username") String username,
            @RequestParam(value = "parentFolderId", required = false) Integer parentFolderId,
            @RequestParam(value = "description", required = false) String description) {

        try {
            // 检查用户是否有编辑权限
            if (!knowledgeSpaceService.hasEditPermission(spaceId, username)) {
                return Result.error("没有上传文档的权限");
            }

            // 检查文件是否为空
            if (file.isEmpty()) {
                return Result.error("上传文件不能为空");
            }

            // 获取文件信息
            String originalFilename = file.getOriginalFilename();
            String fileExtension = getFileExtension(originalFilename);
            String documentType = getDocumentType(fileExtension);
            String storageType = getStorageType(fileExtension);

            // 创建文档对象
            Document document = new Document();
            document.setDocumentName(getFileNameWithoutExtension(originalFilename));
            document.setDocumentType(documentType);
            document.setDocumentDescription(description != null ? description : "上传的" + originalFilename + "文件");
            document.setSpaceId(spaceId);
            document.setParentFolderId(parentFolderId);
            document.setCreatorUsername(username);
            document.setLastEditorUsername(username);
            document.setFileSize(file.getSize());
            document.setOriginalFilename(originalFilename);
            document.setFileExtension(fileExtension);
            document.setMimeType(file.getContentType());
            document.setStorageType(storageType);
            document.setDownloadCount(0);
            document.setVersion(1);
            document.setIsDeleted(false);
            document.setIsLocked(false);
            document.setAutoSaveEnabled(true);
            document.setCreatedAt(LocalDateTime.now());
            document.setUpdatedAt(LocalDateTime.now());

            // 根据存储类型处理文件
            if ("database".equals(storageType)) {
                // txt和md文件存储在数据库中
                String content = processTextFileContent(file, fileExtension);
                document.setContent(content);
                document.setFilePath(null); // 数据库存储不需要文件路径
            } else if ("filesystem".equals(storageType)) {
                // docx和pdf文件存储在文件系统中
                String filePath = saveFileToFileSystem(file, spaceId);
                document.setFilePath(filePath);
                document.setContent(null); // 文件系统存储不在数据库中保存内容
            }

            // 保存文档到数据库
            int result = documentService.createDocument(document);
            if (result > 0) {
                return Result.success("文档上传成功");
            } else {
                return Result.error("文档上传失败");
            }

        } catch (Exception e) {
            return Result.error("上传文档失败: " + e.getMessage());
        }
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        if (filename == null || !filename.contains(".")) {
            return "";
        }
        return filename.substring(filename.lastIndexOf("."));
    }

    /**
     * 获取不带扩展名的文件名
     */
    private String getFileNameWithoutExtension(String filename) {
        if (filename == null || !filename.contains(".")) {
            return filename;
        }
        return filename.substring(0, filename.lastIndexOf("."));
    }

    /**
     * 根据文件扩展名获取文档类型
     */
    private String getDocumentType(String fileExtension) {
        switch (fileExtension.toLowerCase()) {
            case ".md":
                return "markdown";
            case ".txt":
                return "text";
            case ".docx":
                return "docx";
            case ".pdf":
                return "pdf";
            default:
                return "text"; // 默认使用text类型而不是other
        }
    }

    /**
     * 根据文件扩展名确定存储类型
     */
    private String getStorageType(String fileExtension) {
        switch (fileExtension.toLowerCase()) {
            case ".md":
            case ".txt":
                return "database";
            case ".docx":
            case ".pdf":
                return "filesystem";
            default:
                return "filesystem";
        }
    }

    /**
     * 处理文本文件内容，特别是MD文件的格式保持
     */
    private String processTextFileContent(MultipartFile file, String fileExtension) throws IOException {
        byte[] fileBytes = file.getBytes();
        String content;

        // 检测并处理BOM标记
        if (fileBytes.length >= 3 &&
                fileBytes[0] == (byte) 0xEF &&
                fileBytes[1] == (byte) 0xBB &&
                fileBytes[2] == (byte) 0xBF) {
            // 移除UTF-8 BOM
            content = new String(fileBytes, 3, fileBytes.length - 3, "UTF-8");
        } else {
            // 尝试多种编码
            content = detectAndDecodeContent(fileBytes);
        }

        // 标准化换行符
        content = content.replaceAll("\r\n", "\n").replaceAll("\r", "\n");

        // 如果是Markdown文件，使用MarkdownService进行预处理
        if (".md".equalsIgnoreCase(fileExtension)) {
            MarkdownService markdownService = new MarkdownService();
            content = markdownService.preprocessMarkdown(content);
        }

        return content;
    }

    /**
     * 检测文件编码并解码内容
     */
    private String detectAndDecodeContent(byte[] fileBytes) throws IOException {
        // 尝试UTF-8编码
        try {
            String utf8Content = new String(fileBytes, "UTF-8");
            // 检查是否包含UTF-8无效字符
            if (!utf8Content.contains("\uFFFD")) {
                return utf8Content;
            }
        } catch (Exception e) {
            // UTF-8解码失败，继续尝试其他编码
        }

        // 尝试GBK编码
        try {
            return new String(fileBytes, "GBK");
        } catch (Exception e) {
            // GBK解码失败，继续尝试其他编码
        }

        // 尝试ISO-8859-1编码
        try {
            return new String(fileBytes, "ISO-8859-1");
        } catch (Exception e) {
            // 最后使用系统默认编码
            return new String(fileBytes);
        }
    }

    /**
     * 将文件保存到文件系统
     */
    private String saveFileToFileSystem(MultipartFile file, Integer spaceId) throws IOException {
        // 创建上传目录
        String spaceDir = uploadPath + File.separator + "space_" + spaceId;
        Path uploadDir = Paths.get(spaceDir);
        if (!Files.exists(uploadDir)) {
            Files.createDirectories(uploadDir);
        }

        // 生成唯一文件名
        String originalFilename = file.getOriginalFilename();
        String fileExtension = getFileExtension(originalFilename);
        String uniqueFilename = UUID.randomUUID().toString() + fileExtension;

        // 保存文件
        Path filePath = uploadDir.resolve(uniqueFilename);
        Files.copy(file.getInputStream(), filePath);

        // 返回相对路径
        return "space_" + spaceId + File.separator + uniqueFilename;
    }
}